package com.example.composestudy.part6

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.BiasAlignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.*
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.dp
import com.example.composestudy.utils.initialPage
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState


@Composable
fun CustomViewTest() {
//    DrawPoint()
//    DrawLine()
//    StampedPathEffectSample()
//    DrawRect()
//    DrawRoundRect()
    // DrawCircle()
}


@Composable
fun DrawRoundRect() {
    PageItem(text = "DrawRoundRect") {
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawRoundRect(color = Color.Red,
                topLeft = Offset(100f, 100f),
                size = Size(400f, 600f),
                style = Stroke(width = 30f),
                cornerRadius = CornerRadius(50f, 50f)
            )
        }
    }
}

@OptIn(ExperimentalPagerApi::class)
@Composable
fun DrawRect() {
    val pageCount = 4
    // val initialPage = pageCount - 1
    val initialPage = 0.initialPage()
    val state = rememberPagerState(initialPage)
    HorizontalPager(count = pageCount, modifier = Modifier.fillMaxWidth(), state = state) { page ->
        println("currentPage = $currentPage, page = $page, ${page == currentPage}")
        when (page) {
            0 -> DrawRect1()
            1 -> DrawRect2()
            2 -> DrawRect3()
            3 -> DrawRect4()
        }
    }
}

@Composable
private fun DrawRect1() {
    PageItem("DrawRect1") {
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawRect(
                color = Color.Red,
                topLeft = Offset(100f, 100f),
                size = Size(400f, 600f),
            )
        }
    }
}

@Composable
private fun DrawRect2() {
    PageItem(text = "DrawRect2") {
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawRect(color = Color.Green,
                topLeft = Offset(100f, 100f),
                size = Size(400f, 600f),
                style = Stroke(
                    width = 30f
                )
            )
        }
    }
}

@Composable
private fun DrawRect3() {
    PageItem(text = "DrawRect3") {
        // 和DrawRect2完全一样啊！！miter、cap 没啥用啊
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawRect(color = Color.Blue,
                topLeft = Offset(100f, 100f),
                size = Size(400f, 600f),
                style = Stroke(
                    width = 30f,
                    miter = 50f,
                    cap = StrokeCap.Round,
                )
            )
        }
    }
}

@Composable
private fun DrawRect4() {
    PageItem(text = "DrawRect4_StrokeJoin") {
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawRect(color = Color.Red,
                topLeft = Offset(100f, 100f),
                size = Size(400f, 600f),
                style = Stroke(
                    width = 30f,
                    join = StrokeJoin.Bevel, // 会有一个平角
                )
            )
            drawRect(color = Color.Red,
                topLeft = Offset(100f, 800f),
                size = Size(400f, 600f),
                style = Stroke(
                    width = 30f,
                    join = StrokeJoin.Round, // 会有一个圆角
                )
            )
            drawRect(color = Color.Red,
                topLeft = Offset(100f, 1500f),
                size = Size(400f, 600f),
                style = Stroke(width = 30f)
            )
        }
    }
}

@Composable
fun PageItem(text: String, content: @Composable () -> Unit) {
    Box(modifier = Modifier.fillMaxSize()) {
        content()
        Text(
            text = text,
            modifier = Modifier.align(BiasAlignment(0f, 0.8f))
        )
    }
}

@Composable
fun DrawLine() {
    Canvas(modifier = Modifier.fillMaxSize()) {
        drawLine(color = Color.Blue,
            start = Offset(50f, 50f),
            end = Offset(150f, 150f),
            strokeWidth = 30f,
            // cap = StrokeCap.Round
            pathEffect = PathEffect.cornerPathEffect(50f) // 没看出来效果啊
        )
        drawLine(color = Color.Red,
            start = Offset(150f, 150f),
            end = Offset(700f, 300f),
            strokeWidth = 30f,
            // cap = StrokeCap.Round
            // pathEffect = PathEffect.cornerPathEffect(50f)
            // 虚线
            // pathEffect = PathEffect.dashPathEffect(floatArrayOf(30f, 10f), 10f)
            // 一头虚线
            pathEffect = PathEffect.chainPathEffect(PathEffect.cornerPathEffect(100f),
                PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 10f)))
    }
}

@Composable
fun DrawPoint() {
    Column(modifier = Modifier.fillMaxSize()) {
        Text(text = "pointMode = PointMode.Points")
        DrawPointItem(pointMode = PointMode.Points)
        Text(text = "pointMode = PointMode.Lines")
        DrawPointItem(pointMode = PointMode.Lines)
        Text(text = "PointMode.Polygon, StrokeCap.Butt")
        DrawPointItem(pointMode = PointMode.Polygon)
        Text(text = "StrokeCap.Square, cornerPathEffect\n比上面的长一点点")
        DrawPointItem(pointMode = PointMode.Polygon, cap = StrokeCap.Square)
        Text(text = "cap = StrokeCap.Round")
        DrawPointItem(pointMode = PointMode.Polygon, cap = StrokeCap.Round)
        Text(text = "Brush")
        Canvas(modifier = Modifier
            .fillMaxWidth()
            .height(50.dp)) {
            drawPoints(
                brush = Brush.linearGradient(
                    colors = listOf(Color.Red, Color.Green, Color.Blue),
                    start = Offset(80f, center.y - 20f),
                    end = Offset(120f, center.y + 20f)
                ),
                points = listOf(Offset(100f, center.y)),
                pointMode = PointMode.Points,
                strokeWidth = 50f,
                cap = StrokeCap.Round,

                )
        }
    }
}

@Composable
private fun DrawPointItem(
    pointMode: PointMode,
    cap: StrokeCap = StrokeCap.Butt,
) {
    Canvas(modifier = Modifier
        .fillMaxWidth()
        .height(50.dp)) {
        val points = arrayListOf(
            Offset(100f, center.y),
            Offset(300f, center.y),
            Offset(500f, center.y),
            Offset(700f, center.y),
            Offset(900f, center.y),
        )
        drawPoints(
            points = points,
            pointMode = pointMode,
            color = Color.Blue,
            strokeWidth = 30f,
            cap = cap,

            )
    }
}

@Composable
fun StampedPathEffectSample() {
    val size = 20f
    val square = Path().apply {
        lineTo(size, 0f)
        lineTo(size, size)
        lineTo(0f, size)
        close()
    }
    Column(modifier = Modifier
        .fillMaxHeight()
        .wrapContentSize(Alignment.Center)) {
        val canvasModifier = Modifier
            .requiredSize(80.dp)
            .align(Alignment.CenterHorizontally)

        // StampedPathEffectStyle.Morph will modify the lines of the square to be curved to fit
        // the curvature of the circle itself. Each stamped square will be rendered as an arc
        // that is fully contained by the bounds of the circle itself
        Canvas(modifier = canvasModifier) {
            drawCircle(color = Color.Blue)
            drawCircle(color = Color.Red,
                style = Stroke(pathEffect = PathEffect.stampedPathEffect(shape = square,
                    style = StampedPathEffectStyle.Morph,
                    phase = 0f,
                    advance = 30f)))
        }

        Spacer(modifier = Modifier.requiredSize(10.dp))

        // StampedPathEffectStyle.Rotate will draw the square repeatedly around the circle
        // such that each stamped square is centered on the circumference of the circle and is
        // rotated along the curvature of the circle itself
        Canvas(modifier = canvasModifier) {
            drawCircle(color = Color.Blue)
            drawCircle(color = Color.Red,
                style = Stroke(pathEffect = PathEffect.stampedPathEffect(shape = square,
                    style = StampedPathEffectStyle.Rotate,
                    phase = 0f,
                    advance = 30f)))
        }

        Spacer(modifier = Modifier.requiredSize(10.dp))

        // StampedPathEffectStyle.Translate will draw the square repeatedly around the circle
        // with the top left of each stamped square on the circumference of the circle
        Canvas(modifier = canvasModifier) {
            drawCircle(color = Color.Blue)
            drawCircle(color = Color.Red,
                style = Stroke(pathEffect = PathEffect.stampedPathEffect(shape = square,
                    style = StampedPathEffectStyle.Translate,
                    phase = 0f,
                    advance = 30f)))
        }
    }
}
